<{extend name="Public:public" /}>

<{block name="title"}>单文件组件<{/block}>

<{block name="content"}> 
<div class="content guide with-sidebar single-file-components-guide">
  
    
      <div id="ad">
  <!-- <script
    async
    type="text/javascript"
    src="//cdn.carbonads.com/carbon.js?serve=CKYIK2QU&placement=vuejsorg"
    id="_carbonads_js">
  </script> -->
  <a href="https://studio.qcloud.coding.net/campaign/favorite-plugins/?utm_source=vue.js&amp;utm_content=ad1116" target="_blank">
    <img src="/images/coding-net-ad.jpg">
  </a>
</div>

    
  
  
    <h1>单文件组件</h1>
  
  
    <h2 id="介绍"><a href="#介绍" class="headerlink" title="介绍" data-scroll="">介绍</a></h2><p>在很多 Vue 项目中，我们使用 <code>Vue.component</code> 来定义全局组件，紧接着用 <code>new Vue({ el: '#container '})</code> 在每个页面内指定一个容器元素。</p>
<p>这种方式在很多中小规模的项目中运作的很好，在这些项目里 JavaScript 只被用来加强特定的视图。但当在更复杂的项目中，或者你的前端完全由 JavaScript 驱动的时候，下面这些缺点将变得非常明显：</p>
<ul>
<li><strong>全局定义 (Global definitions)</strong> 强制要求每个 component 中的命名不得重复</li>
<li><strong>字符串模板 (String templates)</strong> 缺乏语法高亮，在 HTML 有多行的时候，需要用到丑陋的 <code>\</code></li>
<li><strong>不支持 CSS (No CSS support)</strong> 意味着当 HTML 和 JavaScript 组件化时，CSS 明显被遗漏</li>
<li><strong>没有构建步骤 (No build step)</strong> 限制只能使用 HTML 和 ES5 JavaScript,  而不能使用预处理器，如 Pug (formerly Jade) 和 Babel</li>
</ul>
<p>文件扩展名为 <code>.vue</code> 的 <strong>single-file components(单文件组件)</strong> 为以上所有问题提供了解决方法，并且还可以使用 webpack 或 Browserify 等构建工具。</p>
<p>这是一个文件名为 <code>Hello.vue</code> 的简单实例：</p>
<p><a href="https://gist.github.com/chrisvfritz/e2b6a6110e0829d78fa4aedf7cf6b235" target="_blank" rel="noopener noreferrer"><img src="/images/vue-component.png" alt="单文件组件的示例 (点击查看文本版的代码)" style="display: block; margin: 30px auto;"></a></p>
<p>现在我们获得：</p>
<ul>
<li><a href="https://github.com/vuejs/awesome-vue#source-code-editing" target="_blank" rel="noopener">完整语法高亮</a></li>
<li><a href="https://webpack.js.org/concepts/modules/#what-is-a-webpack-module" target="_blank" rel="noopener">CommonJS 模块</a></li>
<li><a href="https://vue-loader.vuejs.org/zh-cn/features/scoped-css.html" target="_blank" rel="noopener">组件作用域的 CSS</a></li>
</ul>
<p>正如我们说过的，我们可以使用预处理器来构建简洁和功能更丰富的组件，比如 Pug，Babel (with ES2015 modules)，和 Stylus。</p>
<p><a href="https://gist.github.com/chrisvfritz/1c9f2daea9bc078dcb47e9a82e5f7587" target="_blank" rel="noopener noreferrer"><img src="/images/vue-component-with-preprocessors.png" alt="带预处理器的单文件组件的示例 (点击查看文本版的代码)" style="display: block; margin: 30px auto;"></a></p>
<p>这些特定的语言只是例子，你可以只是简单地使用 Babel，TypeScript，SCSS，PostCSS - 或者其他任何能够帮助你提高生产力的预处理器。如果搭配 <code>vue-loader</code> 使用 webpack，它也是把 CSS Modules 当作第一公民来对待的。</p>
<h3 id="怎么看待关注点分离？"><a href="#怎么看待关注点分离？" class="headerlink" title="怎么看待关注点分离？" data-scroll="">怎么看待关注点分离？</a></h3><p>一个重要的事情值得注意，<strong>关注点分离不等于文件类型分离。</strong>在现代 UI 开发中，我们已经发现相比于把代码库分离成三个大的层次并将其相互交织起来，把它们划分为松散耦合的组件再将其组合起来更合理一些。在一个组件里，其模板、逻辑和样式是内部耦合的，并且把他们搭配在一起实际上使得组件更加内聚且更可维护。</p>
<p>即便你不喜欢单文件组件，你仍然可以把 JavaScript、CSS 分离成独立的文件然后做到热重载和预编译。</p>
<figure class="highlight html"><table><tbody><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!-- my-component.vue --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span>&gt;</span>This will be pre-compiled<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"./my-component.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">style</span> <span class="attr">src</span>=<span class="string">"./my-component.css"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br></pre></td></tr></tbody></table></figure>
<h2 id="起步"><a href="#起步" class="headerlink" title="起步" data-scroll="">起步</a></h2><h3 id="例子沙箱"><a href="#例子沙箱" class="headerlink" title="例子沙箱" data-scroll="">例子沙箱</a></h3><p>如果你希望深入了解并开始使用单文件组件，请来 CodeSandbox <a href="https://codesandbox.io/s/o29j95wx9" target="_blank" rel="noopener">看看这个简单的 todo 应用</a>。</p>
<h3 id="针对刚接触-JavaScript-模块开发系统的用户"><a href="#针对刚接触-JavaScript-模块开发系统的用户" class="headerlink" title="针对刚接触 JavaScript 模块开发系统的用户" data-scroll="">针对刚接触 JavaScript 模块开发系统的用户</a></h3><p>有了 <code>.vue</code> 组件，我们就进入了高级 JavaScript 应用领域。如果你没有准备好的话，意味着还需要学会使用一些附加的工具：</p>
<ul>
<li><p><strong>Node Package Manager (NPM)</strong>：阅读 <a href="https://docs.npmjs.com/getting-started/what-is-npm" target="_blank" rel="noopener">Getting Started guide</a> 直到 <em>10: Uninstalling global packages</em>章节。</p>
</li>
<li><p><strong>Modern JavaScript with ES2015/16</strong>：阅读 Babel 的 <a href="https://babeljs.io/docs/learn-es2015/" target="_blank" rel="noopener">Learn ES2015 guide</a>。你不需要立刻记住每一个方法，但是你可以保留这个页面以便后期参考。</p>
</li>
</ul>
<p>在你花一天时间了解这些资源之后，我们建议你参考 <a href="https://github.com/vuejs-templates/webpack" target="_blank" rel="noopener">webpack</a> 模板。只要遵循指示，你就能很快地运行一个用到 <code>.vue</code> 组件，ES2015 和热重载 (hot-reloading) 的 Vue 项目!</p>
<p>想学习更多 webpack 的知识，请移步<a href="https://webpack.js.org/configuration/" target="_blank" rel="noopener">它们的官方文档</a>以及 <a href="https://webpack.academy/p/the-core-concepts" target="_blank" rel="noopener">webpack learning academy</a>。在 webpack 中，每个模块被打包到 bundle 之前都由一个相应的“loader”来转换，Vue 也提供 <a href="https://github.com/vuejs/vue-loader" target="_blank" rel="noopener">vue-loader</a> 插件来执行 <code>.vue</code> 单文件组件 的转换。</p>
<h3 id="针对高级用户"><a href="#针对高级用户" class="headerlink" title="针对高级用户" data-scroll="">针对高级用户</a></h3><p>无论你更钟情 webpack 或是 Browserify，我们为简单的和更复杂的项目都提供了一些文档模板。我们建议浏览 <a href="https://github.com/vuejs-templates" target="_blank" rel="noopener">github.com/vuejs-templates</a>，找到你需要的部分，然后参考 README 中的说明，使用 <a href="https://github.com/vuejs/vue-cli" target="_blank" rel="noopener">vue-cli</a> 工具生成新的项目。</p>
<p>模板中使用 <a href="https://webpack.js.org/" target="_blank" rel="noopener">webpack</a>，一个模块加载器加载多个模块然后构建成最终应用。为了进一步了解 webpack，可以看 <a href="https://www.youtube.com/watch?v=WQue1AN93YU" target="_blank" rel="noopener">官方介绍视频</a>。如果你有基础，可以看 <a href="https://egghead.io/courses/using-webpack-for-production-javascript-applications" target="_blank" rel="noopener">在 Egghead.io 上的 webpack 进阶教程</a>。</p>

  
  
    <div class="guide-links">
      
      
        <span>← <a href="/v2/guide/deployment.html">生产环境部署</a></span>
      
      
      
        <span style="float: right;"><a href="/v2/guide/unit-testing.html">单元测试</a> →</span>
      
    </div>
  
  <div class="footer">
      <script src="//m.servedby-buysellads.com/monetization.js" type="text/javascript"></script>
<div class="bsa-cpc"></div>
<script>
  (function(){
    if(typeof _bsa !== 'undefined' && _bsa) {
    _bsa.init('default', 'CKYD62QM', 'placement:vuejsorg', {
      target: '.bsa-cpc',
      align: 'horizontal',
      disable_css: 'true'
    });
      }
  })();
</script>

    发现错误？想参与编辑？
    <a href="https://github.com/vuejs/cn.vuejs.org/blob/master/src/v2/guide/single-file-components.md" target="_blank">
      在 GitHub 上编辑此页！
    </a>
  </div>
</div>
<{/block}>
